﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NetManager.Core.Entities;
using System.IO;
using NetManager.Core.Services;
using AutoMapper;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using System.Security;
using System.ComponentModel;

namespace NetManager.LocalBrowser.Services
{
    class LocalContentService : IContentService
    {
        public LocalContentService()
        {
            ConfigureMapper();
            _currentPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        }

        public string CurrentPath
        {
            get { return _currentPath; }
            set { _currentPath = value; }
        }

        public void Run(string path)
        {
            if (!string.IsNullOrEmpty(path))
            {
                try
                {
                    var file = new FileInfo(path);
                    if (file.Exists)
                        System.Diagnostics.Process.Start(path);
                }
                catch (FileNotFoundException) { }
                catch (ObjectDisposedException) { }
                catch (Win32Exception) { }
            }
        }

        public bool ValidatePath(string path)
        {
            if (string.IsNullOrEmpty(path))
                return false;

            if (!Path.IsPathRooted(path))
                return false;

            string root = Path.GetPathRoot(path);
            if (!Environment.GetLogicalDrives().Contains(root))
                return false;

            Regex r = new Regex(@"^(([a-zA-Z]\:)|(\\))(\\{1}|((\\{1})[^\\]([^/:*?<>""|]*))+)$");
            return r.IsMatch(path);
        }

        public bool IsDirectory(string path)
        {
            if (string.IsNullOrEmpty(path))
                return false;

            try
            {
                var dir = new DirectoryInfo(path);
                return dir.Exists;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public bool IsFile(string path)
        {
            if (string.IsNullOrEmpty(path))
                return false;

            try
            {
                var file = new FileInfo(path);
                return file.Exists;
            }
            catch (Exception)
            {
                return false;
            }
        }

        public IEnumerable<ContentItem> GetContent(string path, out string errorMessage)
        {
            if (string.IsNullOrEmpty(path))
                throw new ArgumentNullException("path");

            _currentPath = path;
            errorMessage = null;

            List<ContentItem> content = new List<ContentItem>();

            try
            {
                var currentDir = new DirectoryInfo(path);
                var parent = Mapper.Map<DirectoryInfo, ContentItem>(currentDir.Parent);

                if (parent != null)
                {
                    parent.Name = "..";
                    content.Add(parent);
                }

                foreach (var dir in currentDir.GetDirectories())
                {
                    if ((dir.Attributes & FileAttributes.Hidden) == 0)
                        content.Add(Mapper.Map<DirectoryInfo, ContentItem>(dir));
                }

                foreach (var file in currentDir.GetFiles())
                {
                    content.Add(Mapper.Map<FileInfo, ContentItem>(file));
                }
            }
            catch (SecurityException e) { errorMessage = e.Message; }
            catch (DirectoryNotFoundException e) { errorMessage = e.Message; }
            catch (UnauthorizedAccessException e) { errorMessage = e.Message; }

            return content;
        }

        private void ConfigureMapper()
        {
            Mapper.CreateMap<DirectoryInfo, ContentItem>().ForMember(
                dest => dest.Extension,
                opts => opts.MapFrom(src => "<dir>"));
            Mapper.CreateMap<FileInfo, ContentItem>();
        }

        private string _currentPath;
    }
}
